package com.olc.railing.busniess;



import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothGatt;
import android.bluetooth.BluetoothGattCharacteristic;
import android.bluetooth.BluetoothGattDescriptor;
import android.bluetooth.BluetoothGattServer;
import android.bluetooth.BluetoothGattServerCallback;
import android.bluetooth.BluetoothGattService;
import android.bluetooth.BluetoothManager;
import android.bluetooth.le.AdvertiseCallback;
import android.bluetooth.le.AdvertiseData;
import android.bluetooth.le.AdvertiseSettings;
import android.bluetooth.le.BluetoothLeAdvertiser;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.os.Build;
import android.os.ParcelUuid;
import android.os.SystemClock;
import android.text.TextUtils;
import android.util.Log;
import android.widget.Toast;

import androidx.annotation.RequiresApi;


import com.olc.railing.base.BaseApplication;
import com.olc.railing.utils.MyLog;
import com.olc.railing.utils.SharedUtils;
import com.tianyuxinghang.sxmobileterm.utils.SPUtils;

import java.util.Arrays;
import java.util.UUID;

@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
public class BLEServer {
    private static final String TAG = "BLEServer";
    private static BLEServer instance = null;
    private  BluetoothGattServer mBluetoothGattServer;
    private BLEServerCallback bleServerCallback = null;

    public static final UUID UUID_MSG_SERVICE = UUID.fromString("10000000-0000-0000-0000-000000000000"); //自定义UUID
    public static final UUID UUID_CHAR_READ_NOTIFY = UUID.fromString("11000000-0000-0000-0000-000000000000");
    public static final UUID UUID_DESC_NOTIFY = UUID.fromString("11100000-0000-0000-0000-000000000000");
    public static final UUID UUID_CHAR_WRITE = UUID.fromString("12000000-0000-0000-0000-000000000000");


    private String data ="";

    // BLE服务端Callback
    private BluetoothGattServerCallback mBluetoothGattServerCallback = new BluetoothGattServerCallback() {
        @Override
        public void onConnectionStateChange(BluetoothDevice device, int status, int newState) {
            Log.i(TAG, String.format("onConnectionStateChange:%s,%s,%s,%s", device.getName(), device.getAddress(), status, newState));
            bleServerCallback.onConnectStateChange(device,status,newState);
            //logTv(String.format(status == 0 ? (newState == 2 ? "与[%s]连接成功" : "与[%s]连接断开") : ("与[%s]连接出错,错误码:" + status), device));
        }

        @Override
        public void onServiceAdded(int status, BluetoothGattService service) {
            Log.i(TAG, String.format("onServiceAdded:%s,%s", status, service.getUuid()));
            /// logTv(String.format(status == 0 ? "添加服务[%s]成功" : "添加服务[%s]失败,错误码:" + status, service.getUuid()));
        }

        @Override
        public void onCharacteristicReadRequest(BluetoothDevice device, int requestId, int offset, BluetoothGattCharacteristic characteristic) {
            Log.i(TAG, String.format("onCharacteristicReadRequest:%s,%s,%s,%s,%s", device.getName(), device.getAddress(), requestId, offset, characteristic.getUuid()));
            String response = "CHAR_" + (int) (Math.random() * 100); //模拟数据
            mBluetoothGattServer.sendResponse(device, requestId, BluetoothGatt.GATT_SUCCESS, offset, response.getBytes());// 响应客户端
            /// logTv("客户端读取Characteristic[" + characteristic.getUuid() + "]:\n" + response);
        }

        @Override
        public void onCharacteristicWriteRequest(BluetoothDevice device, int requestId, BluetoothGattCharacteristic characteristic, boolean preparedWrite, boolean responseNeeded, int offset, byte[] requestBytes) {
            // 获取客户端发过来的数据
            String requestStr =new String(requestBytes);
            Log.i(TAG, String.format("onCharacteristicWriteRequest:%s", requestStr));
            data += requestStr;
            mBluetoothGattServer.sendResponse(device, requestId, BluetoothGatt.GATT_SUCCESS, offset, requestBytes);// 响应客户端

            if(!TextUtils.isEmpty(data)&&data.startsWith("100")&&data.endsWith("FFFF")){
                String wifiInfo = data.substring(data.indexOf("100")+3,data.lastIndexOf("FFFF"));
                Log.i(TAG, String.format("wifiInfo:%s", wifiInfo));
                String[] strings = wifiInfo.split("\\|");
                boolean result =  WifiAutoConnectManager.getInstance(BaseApplication.getApplication()).connect(strings[0],strings[1]);
                if(!result){
                    result =  WifiAutoConnectManager.getInstance(BaseApplication.getApplication()).connect(strings[0],strings[1]);
                }
                bleServerCallback.configWifi(result);
                data = "";
            }else if(!TextUtils.isEmpty(data)&&data.startsWith("200")&&data.endsWith("FFFF")){
                Log.i(TAG, String.format("onCharacteristicWriteRequest:%s", data));
                String oilNo = data.substring(data.indexOf("200")+3,data.lastIndexOf("FFFF"));
                Log.i(TAG, String.format("oilNo:%s", oilNo));
                SharedUtils.setOilGunNo(BaseApplication.getApplication(),oilNo);
                bleServerCallback.configOilNo(!TextUtils.isEmpty(oilNo));
                data = "";
            }else if(!TextUtils.isEmpty(data)&&data.startsWith("300")&&data.endsWith("FFFF")){
                Log.i(TAG, String.format("onCharacteristicWriteRequest:%s", data));
                String ipAdress = data.substring(data.indexOf("300")+3,data.lastIndexOf("FFFF"));
                Log.i(TAG, String.format("IP_ADRESS:%s", ipAdress));
                SharedUtils.setIpAdress(BaseApplication.getApplication(),ipAdress);
                bleServerCallback.configIpAdress(!TextUtils.isEmpty(ipAdress));
                data = "";
            }
            // logTv("客户端写入Characteristic[" + characteristic.getUuid() + "]:\n" + requestStr);
        }

        @Override
        public void onDescriptorReadRequest(BluetoothDevice device, int requestId, int offset, BluetoothGattDescriptor descriptor) {
            Log.i(TAG, String.format("onDescriptorReadRequest:%s,%s,%s,%s,%s", device.getName(), device.getAddress(), requestId, offset, descriptor.getUuid()));
            String response = "DESC_" + (int) (Math.random() * 100); //模拟数据
            mBluetoothGattServer.sendResponse(device, requestId, BluetoothGatt.GATT_SUCCESS, offset, response.getBytes()); // 响应客户端
            // logTv("客户端读取Descriptor[" + descriptor.getUuid() + "]:\n" + response);
        }

        @Override
        public void onDescriptorWriteRequest(final BluetoothDevice device, int requestId, BluetoothGattDescriptor descriptor, boolean preparedWrite, boolean responseNeeded, int offset, byte[] value) {
            // 获取客户端发过来的数据
            String valueStr = Arrays.toString(value);
            Log.i(TAG, String.format("onDescriptorWriteRequest:%s,%s,%s,%s,%s,%s,%s,%s", device.getName(), device.getAddress(), requestId, descriptor.getUuid(),
                    preparedWrite, responseNeeded, offset, valueStr));
            mBluetoothGattServer.sendResponse(device, requestId, BluetoothGatt.GATT_SUCCESS, offset, value);// 响应客户端
            // logTv("客户端写入Descriptor[" + descriptor.getUuid() + "]:\n" + valueStr);

            // 简单模拟通知客户端Characteristic变化
            if (Arrays.toString(BluetoothGattDescriptor.ENABLE_NOTIFICATION_VALUE).equals(valueStr)) { //是否开启通知
                final BluetoothGattCharacteristic characteristic = descriptor.getCharacteristic();
                new Thread(new Runnable() {
                    @Override
                    public void run() {
                        for (int i = 0; i < 5; i++) {
                            SystemClock.sleep(3000);
                            String response = "CHAR_" + (int) (Math.random() * 100); //模拟数据
                            characteristic.setValue(response);
                            mBluetoothGattServer.notifyCharacteristicChanged(device, characteristic, false);
                            // logTv("通知客户端改变Characteristic[" + characteristic.getUuid() + "]:\n" + response);
                        }
                    }
                }).start();
            }
        }

        @Override
        public void onExecuteWrite(BluetoothDevice device, int requestId, boolean execute) {
            Log.i(TAG, String.format("onExecuteWrite:%s,%s,%s,%s", device.getName(), device.getAddress(), requestId, execute));
        }

        @Override
        public void onNotificationSent(BluetoothDevice device, int status) {
            Log.i(TAG, String.format("onNotificationSent:%s,%s,%s", device.getName(), device.getAddress(), status));
        }

        @Override
        public void onMtuChanged(BluetoothDevice device, int mtu) {
            Log.i(TAG, String.format("onMtuChanged:%s,%s,%s", device.getName(), device.getAddress(), mtu));
        }
    };
    private BluetoothAdapter mBluetoothAdapter;
    private BluetoothLeAdvertiser bluetoothLeAdvertiser;
    private BluetoothManager mBluetoothManager;

    public synchronized static BLEServer getInstance()
    {
        if(instance == null)
            instance = new BLEServer();

        return instance;
    }
    public void initBlueTooth(Context context,BluetoothAdapter mBluetoothAdapter,BluetoothManager mBluetoothManager,BLEServerCallback bleServerCallback){
        this.bleServerCallback = bleServerCallback;
        this.mBluetoothManager = mBluetoothManager;
        this.mBluetoothAdapter = mBluetoothAdapter;
        if (bluetoothLeAdvertiser == null) {
            bluetoothLeAdvertiser = mBluetoothAdapter.getBluetoothLeAdvertiser();
        }

        // =============启动BLE蓝牙服务端=====================================================================================
        BluetoothGattService service = new BluetoothGattService(UUID_MSG_SERVICE, BluetoothGattService.SERVICE_TYPE_PRIMARY);
        //添加可读+通知 characteristic
        BluetoothGattCharacteristic characteristicRead = new BluetoothGattCharacteristic(UUID_CHAR_READ_NOTIFY,
                BluetoothGattCharacteristic.PROPERTY_READ | BluetoothGattCharacteristic.PROPERTY_NOTIFY, BluetoothGattCharacteristic.PERMISSION_READ);
        characteristicRead.addDescriptor(new BluetoothGattDescriptor(UUID_DESC_NOTIFY, BluetoothGattCharacteristic.PERMISSION_WRITE));
        service.addCharacteristic(characteristicRead);
        //添加可写characteristic
        BluetoothGattCharacteristic characteristicWrite = new BluetoothGattCharacteristic(UUID_CHAR_WRITE,
                BluetoothGattCharacteristic.PROPERTY_WRITE, BluetoothGattCharacteristic.PERMISSION_WRITE);
        service.addCharacteristic(characteristicWrite);
        mBluetoothGattServer = mBluetoothManager.openGattServer(context, mBluetoothGattServerCallback);
        if(mBluetoothGattServer!=null){
            mBluetoothGattServer.addService(service);
        }
       // restartAdvertising();
    }

    public void restartAdvertising() {

        stopAdvertising();
        startAdvertising();
    }
    private void startAdvertising() {
        MyLog.d(MyLog.TAG, "ble--startAdvertising: " );
        if (bluetoothLeAdvertiser == null) return;
      //  MyLog.d(MyLog.TAG,"启动蓝牙广播 restartAdvertising");
        //广播数据(必须，广播启动就会发送)
        AdvertiseData  advertiseData = new AdvertiseData.Builder()
                .setIncludeDeviceName(true) //包含蓝牙名称
                .setIncludeTxPowerLevel(true) //包含发射功率级别
                .addManufacturerData(1, new byte[]{23, 33}) //设备厂商数据，自定义
                .build();

        AdvertiseSettings settings = new AdvertiseSettings.Builder()
                .setAdvertiseMode(AdvertiseSettings.ADVERTISE_MODE_LOW_LATENCY)
                .setConnectable(true)
                .setTxPowerLevel(AdvertiseSettings.ADVERTISE_TX_POWER_HIGH)
                .build();

        AdvertiseData scanResponseData = new AdvertiseData.Builder()
                .addManufacturerData(2, new byte[]{66, 66}) //设备厂商数据，自定义
                .addServiceUuid(new ParcelUuid(UUID_MSG_SERVICE)) //服务UUID
//                .addServiceData(new ParcelUuid(UUID_SERVICE), new byte[]{2}) //服务数据，自定义
                .build();


        bluetoothLeAdvertiser.startAdvertising(settings, advertiseData, scanResponseData, mAdvertiseCallback);
    }

    private void stopAdvertising() {
        MyLog.d(MyLog.TAG, "ble--stopAdvertising"+mBluetoothAdapter);
        if (mBluetoothAdapter == null) return;
      //  MyLog.d(MyLog.TAG, "BLE广播关闭"+bluetoothLeAdvertiser + " "+mBluetoothAdapter.isEnabled() );
        if (!mBluetoothAdapter.isEnabled() || bluetoothLeAdvertiser == null) return;
        // MyLog.d(MyLog.TAG, "BLE广播关闭");
         bluetoothLeAdvertiser.stopAdvertising(mAdvertiseCallback);
    }
    private android.bluetooth.le.AdvertiseCallback mAdvertiseCallback = new android.bluetooth.le.AdvertiseCallback() {
        @Override
        public void onStartSuccess(AdvertiseSettings settingsInEffect) {
            // ToastUtils.toast(MainActivity.this, "开门中...");
            MyLog.d(MyLog.TAG, "BLE广播开启成功");
        }

        @Override
        public void onStartFailure(int errorCode) {
            MyLog.d(MyLog.TAG, "BLE广播开启失败,错误码:" + errorCode);
        }
    };

    public interface BLEServerCallback {
        void onAdvertiseEnable(boolean isSuccess);
        void onConnectStateChange(BluetoothDevice device, int status, int newStatus);
        void onPrintLog(String log);
        void onPrintMsg(String msg);
        void configWifi(boolean reslt);
        void configOilNo(boolean reslt);
        void configIpAdress(boolean reslt);
        String onReadRequest(UUID uuid);
    }

}

